"""
!/usr/bin/env python
-*- coding: utf-8 -*-
@Author  : MarkJia
@Site    : 
@File    : base_page.py
"""

"""
封装所有页面对象共性的操作。比如：driver 的实例化
"""

import time
import yaml
from selenium import webdriver
from selenium.webdriver.common.by import By
from webtest.autowebui.utils.Logger import logger
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions


class BasePage:
    """与浏览器 driver 交互"""

    # 设定 base_url
    _base_url = None

    """
    当子类没有构造函数时，在实例化的过程中，会自动调用父类的构造函数
    所以：每个 QiYeWeiXin_PO　在实例化过程中，都会执行构造函数的逻辑
    问题：如何避免　driver　的重复实例化
    """

    def __init__(self, base_driver=None):

        # 如果 base_driver 为真，则不需要重复实例化操作
        # 为保证后面的子类在使用过程中，都具有 driver 属性，所以都需要做赋值操作
        if base_driver:
            self.driver = base_driver

        # 如果 base_driver 为 None/假，则需要对 Driver 进行实例化
        else:
            self.driver = webdriver.Chrome()
            self.driver.maximize_window()
            self.driver.implicitly_wait(10)
            # 1、访问企业微信主页面
            # 当 base_url 不为空时，直接访问子类本身
            if self._base_url != None:
                # 当前的 URL  不是以 http 开头
                # if not self.current_url.startswith('http'):
                self.driver.get(self._base_url)
                # ２、植入 cookie
                # 从文件中 读取 cookie
                cookies = yaml.safe_load(open('../data/cookie.yaml'))

                for cookie in cookies:
                    self.driver.add_cookie(cookie)
                time.sleep(3)
                # 4、再次访问企业微信页面，不用扫码，自动登录
                self.driver.get(self._base_url)

    # 对selenium原生方法二次封装（项目自定义父类方法），为 QiYeWeiXin_PO 页面对象提供父类好用的方法
    # 可以加上日志，错误截图，添加异常操作等

    # 访问 url
    def open(self, url):
        logger.info(f'访问网址{url}')
        self.driver.get(url)
        self.driver.maximize_window()

    # 截图并保存操作
    def screenshot(self):
        current_time = time.strftime('%Y-%m-%d %H-%M-%S')
        pic_path = '../logs/screenshot' + current_time + '.png'
        self.driver.save_screenshot(pic_path)

    # 点击操作
    def click(self, loc):
        try:
            logger.info(f'正在点击{loc}元素')
            self.find_ele(loc).click()
        except Exception as e:
            self.screenshot()
            logger.error(f'错误信息为：{e}')

    # 定位元素方法
    def find_ele(self, loc):
        logger.info(f'正在定位{loc}元素')
        # 如果传入元组，则做解包操作
        res = self.driver.find_element(*loc)
        return res

    # 定位所有元素方法
    def find_eles(self, loc):
        logger.info(f'正在定位{loc}元素')
        # 如果传入元组，则做解包操作
        res = self.driver.find_elements(*loc)
        return res

    # 等待
    def wait(self, time_):
        logger.info(f'等待时间{time_}s')
        time.sleep(time_)

    # 关闭浏览器
    def quit_(self):
        logger.info('退出')
        self.driver.quit()

    # 最大化
    def maxSize(self):
        logger.info('最大化')
        self.driver.maximize_window()

    # 刷新浏览器
    def refresh(self):
        self.driver.refresh()

    # 显式等待，等待某个元素可见
    def wait_visible(self, locator):
        WebDriverWait(self.driver, 10).until(expected_conditions.visibility_of_element_located(locator))

    # 显式等待，等待某个元素存在
    def wait_exist(self, locator):
        WebDriverWait(self.driver, 10, 2).until(expected_conditions.presence_of_element_located(locator))

    # 显式等待，等待某个元素可以被点击
    def wait_clickable(self, locator):
        WebDriverWait(self.driver, 10, 2).until(expected_conditions.element_to_be_clickable(locator))

    # 等待某个字段出现
    def waitUntilPagecontions(self, message):
        logger.info(f'正在获取页面{message}字段')
        time.sleep(2)
        msg = self.driver.find_element(By.XPATH, f'//*[contains(text(),"{message}")]').text
        return msg

    # 输入框输入内容方法
    def input_(self, loc, text):
        try:
            logger.info(f'在定位{loc}元素，输入{text}内容')
            self.find_ele(loc).clear()
            self.find_ele(loc).send_keys(text)
        except Exception as e:
            self.screenshot()
            logger.error(f'错误日志{e}')
